/*
 * kernel/cpu.c
 *
 * last modified by ChenJie at 2007.07.27
 *
 */
int printk(const char *fmt, ...);
const char * memcpy(char *dest, const char *src, int length);
void cpu_info(void)
{
	char cpuid[200];
	unsigned long eax, ebx, ecx, edx;
	asm volatile ("CPUID":"=a"(eax),"=b"(ebx),"=c"(ecx),"=d"(edx):"a"(0));
	memcpy(&cpuid[0], (const char *)&ebx, 4);
	memcpy(&cpuid[4], (const char *)&edx, 4);
	memcpy(&cpuid[8], (const char *)&ecx, 4);
	//memcpy(&cpuid[13], (const char *)&eax, 4);
	cpuid[17] = 0;
	printk("CPU:%s %x\n\r", cpuid, &eax);
	//memcpy(&cpuid[0], &ebx, 4);
	asm volatile ("CPUID":"=a"(eax),"=b"(ebx),"=c"(ecx),"=d"(edx):"a"(1));
	printk("CPU:Processor Type = ");
	switch((eax&0x00003000)>>12){
		case 0:
			printk("Original OEM Processor\n\r");
			break;
		case 1:
			printk("Inter OverDrive(R) Processor\n\r");
			break;
		case 2:
			printk("Dual processor * \n\r");
			break;
		case 3:
			printk("Intel reserved.\n\r");
			break;
	};
	printk("CPU:Family = %d\n\r", (eax&0x00000f00)>>8);
	printk("CPU:Model = %d\n\r", (eax&0x000000f0)>>4);
	printk("CPU:Stepping ID = %d\n\r", (eax&0x0000000f));
	printk("CPU:Features = ");
	if((edx>>23)&0x00000001) printk("MMX ");
	if((edx>>15)&0x00000001) printk("CMOV ");
	if((edx>>14)&0x00000001) printk("MCA ");
	if((edx>>13)&0x00000001) printk("PGE ");
	if((edx>>12)&0x00000001) printk("MTRR ");
	if((edx>>9)&0x00000001) printk("APIC ");
	if((edx>>8)&0x00000001) printk("CXS ");
	if((edx>>7)&0x00000001) printk("MCE ");
	if((edx>>6)&0x00000001) printk("PAE ");
	if((edx>>5)&0x00000001) printk("MSR ");
	if((edx>>4)&0x00000001) printk("TSC ");
	if((edx>>3)&0x00000001) printk("PSE ");
	if((edx>>2)&0x00000001) printk("DE ");
	if((edx>>1)&0x00000001) printk("VME ");
	if((edx>>0)&0x00000001) printk("FPU \n\r");


	asm volatile ("CPUID":"=a"(eax),"=b"(ebx),"=c"(ecx),"=d"(edx):"a"(2));
}
